package com.mars.admin.modules.app;

import com.mars.admin.framework.common.Result;
import com.mars.admin.framework.common.annotation.OperationLog;
import com.mars.admin.framework.enums.BusinessType;
import com.mars.admin.modules.base.controller.BaseController;
import com.mars.admin.modules.user.dto.FollowRequest;
import com.mars.admin.modules.user.entity.User;
import com.mars.admin.modules.user.service.IUserFollowService;
import com.mars.admin.modules.user.service.IUserService;
import com.mars.admin.modules.user.vo.FollowStatusVO;
import com.mars.admin.modules.user.vo.UserInfoVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import cn.dev33.satoken.stp.StpUtil;

import java.util.List;

/**
 * 用户Controller
 * 继承BaseController获得基础的增删改查功能
 *
 * @author Mars
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理相关接口")
@AllArgsConstructor
public class UserController extends BaseController<User, Long> {

    private final IUserService userService;
    private final IUserFollowService userFollowService;


    /**
     * 获取当前登录用户信息
     */
    @Operation(summary = "获取当前用户信息", description = "获取当前登录用户的详细信息")
    @GetMapping("/userinfo")
    public Result<UserInfoVO> getUserInfo() {
        UserInfoVO currentUser = userService.getCurrentUser();
        return Result.success("获取用户信息成功", currentUser);
    }


    /**
     * 根据用户Id获取用户信息
     */
    @Operation(summary = "根据用户Id获取用户信息", description = "根据用户Id获取用户信息")
    @GetMapping("/otherUserInfo")
    public Result<UserInfoVO> otherUserInfo(Long userId) {
        UserInfoVO currentUser = userService.getOtherUserInfo(userId);
        return Result.success("获取用户信息成功", currentUser);
    }




    /**
     * 更新用户信息
     */
    @PostMapping("/update")
    @Operation(summary = "更新用户信息", description = "更新用户信息")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE, description = "更新用户：#{#user.username}")
    public Result<Boolean> updateUser(@RequestBody User user) {
        boolean success = userService.updateUser(user);
        return Result.of(success, "更新成功", "更新失败");
    }

    /**
     * 修改用户状态
     */
    @PostMapping("/changeStatus")
    @Operation(summary = "修改用户状态", description = "启用/禁用用户")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE, description = "修改用户状态：用户ID#{#userId}，状态#{#status}")
    public Result<Boolean> changeStatus(@Parameter(description = "用户ID") @RequestParam Long userId, @Parameter(description = "状态") @RequestParam Integer status) {
        boolean success = userService.changeStatus(userId, status);
        return Result.of(success, "状态修改成功", "状态修改失败");
    }

    /**
     * 重置用户密码
     */
    @PostMapping("/resetPassword")
    @Operation(summary = "重置用户密码", description = "重置用户密码为123456")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE, description = "重置用户密码：用户ID#{#userId}")
    public Result<Boolean> resetPassword(@Parameter(description = "用户ID") @RequestParam Long userId) {
        boolean success = userService.resetPassword(userId, "123456");
        return Result.of(success, "密码重置成功", "密码重置失败");
    }

    /**
     * 修改用户密码
     */
    @PostMapping("/changePassword")
    @Operation(summary = "修改用户密码", description = "用户修改自己的密码")
    public Result<Boolean> changePassword(@Parameter(description = "用户ID") @RequestParam Long userId, @Parameter(description = "旧密码") @RequestParam String oldPassword, @Parameter(description = "新密码") @RequestParam String newPassword) {
        boolean success = userService.changePassword(userId, oldPassword, newPassword);
        return Result.of(success, "密码修改成功", "密码修改失败");
    }

    /**
     * 更新用户等级
     */
    @PostMapping("/updateLevel")
    @Operation(summary = "更新用户等级", description = "更新用户等级和经验值")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE, description = "更新用户等级：用户ID#{#userId}，等级#{#level}")
    public Result<Boolean> updateLevel(@Parameter(description = "用户ID") @RequestParam Long userId, @Parameter(description = "等级") @RequestParam Integer level, @Parameter(description = "经验值") @RequestParam Integer experience) {
        boolean success = userService.updateUserLevel(userId, level, experience);
        return Result.of(success, "等级更新成功", "等级更新失败");
    }

    /**
     * 更新用户积分
     */
    @PostMapping("/updatePoints")
    @Operation(summary = "更新用户积分", description = "增加或减少用户积分")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE, description = "更新用户积分：用户ID#{#userId}，积分变化#{#points}")
    public Result<Boolean> updatePoints(@Parameter(description = "用户ID") @RequestParam Long userId, @Parameter(description = "积分变化量") @RequestParam Integer points) {
        boolean success = userService.updateUserPoints(userId, points);
        return Result.of(success, "积分更新成功", "积分更新失败");
    }

    /**
     * 更新用户认证状态
     */
    @PostMapping("/updateVerified")
    @Operation(summary = "更新用户认证状态", description = "更新用户认证状态")
    @OperationLog(title = "用户管理", businessType = BusinessType.UPDATE, description = "更新用户认证：用户ID#{#userId}，认证状态#{#isVerified}")
    public Result<Boolean> updateVerified(@Parameter(description = "用户ID") @RequestParam Long userId, @Parameter(description = "是否认证") @RequestParam Integer isVerified, @Parameter(description = "认证类型") @RequestParam Integer verifiedType) {
        boolean success = userService.updateVerifiedStatus(userId, isVerified, verifiedType);
        return Result.of(success, "认证状态更新成功", "认证状态更新失败");
    }

    /**
     * 更新个人信息
     */
    @PostMapping("/updateUserInfo")
    @Operation(summary = "更新个人信息", description = "用户更新自己的个人信息")
    public Result<Boolean> updatePersonalInfo(@RequestBody User user) {
        boolean success = userService.updatePersonalInfo(user);
        return Result.of(success, "个人信息更新成功", "个人信息更新失败");
    }

    /**
     * 绑定第三方账号
     */
    @PostMapping("/bindThirdParty")
    @Operation(summary = "绑定第三方账号", description = "绑定微信或QQ账号")
    public Result<Boolean> bindThirdPartyAccount(@Parameter(description = "用户ID") @RequestParam Long userId, @Parameter(description = "平台类型") @RequestParam String platform, @Parameter(description = "第三方OpenID") @RequestParam String openid) {
        boolean success = userService.bindThirdPartyAccount(userId, platform, openid);
        return Result.of(success, "绑定成功", "绑定失败");
    }

    /**
     * 解绑第三方账号
     */
    @PutMapping("/unbindThirdParty")
    @Operation(summary = "解绑第三方账号", description = "解绑微信或QQ账号")
    public Result<Boolean> unbindThirdPartyAccount(@Parameter(description = "用户ID") @RequestParam Long userId, @Parameter(description = "平台类型") @RequestParam String platform) {
        boolean success = userService.unbindThirdPartyAccount(userId, platform);
        return Result.of(success, "解绑成功", "解绑失败");
    }

    /**
     * 根据用户名查询用户
     */
    @GetMapping("/getByUsername")
    @Operation(summary = "根据用户名查询用户", description = "根据用户名查询用户信息")
    public Result<User> getByUsername(@Parameter(description = "用户名") @RequestParam String username) {
        User user = userService.selectByUsername(username);
        if (user != null) {
            return Result.success(user);
        } else {
            return Result.error("用户不存在");
        }
    }

    /**
     * 根据手机号查询用户
     */
    @GetMapping("/getByPhone")
    @Operation(summary = "根据手机号查询用户", description = "根据手机号查询用户信息")
    public Result<User> getByPhone(@Parameter(description = "手机号") @RequestParam String phone) {
        User user = userService.selectByPhone(phone);
        if (user != null) {
            return Result.success(user);
        } else {
            return Result.error("用户不存在");
        }
    }

    /**
     * 根据等级查询用户
     */
    @GetMapping("/getByLevel")
    @Operation(summary = "根据等级查询用户", description = "根据等级查询用户列表")
    public Result<List<User>> getByLevel(@Parameter(description = "用户等级") @RequestParam Integer level) {
        List<User> users = userService.selectByLevel(level);
        return Result.success(users);
    }


    /**
     * 查询用户排行榜
     */
    @GetMapping("/getUserRanking")
    @Operation(summary = "查询用户排行榜", description = "按积分查询用户排行榜")
    public Result<List<User>> getUserRanking(@Parameter(description = "数量限制") @RequestParam(defaultValue = "10") Integer limit) {
        List<User> users = userService.selectUserRanking(limit);
        return Result.success(users);
    }

    /**
     * 校验用户名唯一性
     */
    @GetMapping("/checkUsernameUnique")
    @Operation(summary = "校验用户名唯一性", description = "校验用户名是否已存在")
    public Result<Boolean> checkUsernameUnique(@Parameter(description = "用户名") @RequestParam String username, @Parameter(description = "用户ID") @RequestParam(required = false) Long userId) {
        boolean unique = userService.checkUsernameUnique(username, userId);
        return Result.success(unique);
    }

    /**
     * 校验手机号唯一性
     */
    @GetMapping("/checkPhoneUnique")
    @Operation(summary = "校验手机号唯一性", description = "校验手机号是否已存在")
    public Result<Boolean> checkPhoneUnique(@Parameter(description = "手机号") @RequestParam String phone, @Parameter(description = "用户ID") @RequestParam(required = false) Long userId) {
        boolean unique = userService.checkPhoneUnique(phone, userId);
        return Result.success(unique);
    }

    /**
     * 校验邮箱唯一性
     */
    @GetMapping("/checkEmailUnique")
    @Operation(summary = "校验邮箱唯一性", description = "校验邮箱是否已存在")
    public Result<Boolean> checkEmailUnique(@Parameter(description = "邮箱") @RequestParam String email, @Parameter(description = "用户ID") @RequestParam(required = false) Long userId) {
        boolean unique = userService.checkEmailUnique(email, userId);
        return Result.success(unique);
    }

    // ==================== 关注相关接口 ====================

    /**
     * 关注用户
     */
    @PostMapping("/follow")
    @Operation(summary = "关注用户", description = "关注指定用户")
    @OperationLog(title = "用户关注", businessType = BusinessType.INSERT, description = "关注用户：#{#request.followUserId}")
    public Result<Boolean> followUser(@RequestBody FollowRequest request) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();

        // 调用服务层方法
        boolean success = userFollowService.followUser(currentUserId, request.getFollowUserId());
        return Result.of(success, "关注成功", "关注失败");
    }

    /**
     * 取消关注用户
     */
    @PostMapping("/unfollow")
    @Operation(summary = "取消关注用户", description = "取消关注指定用户")
    @OperationLog(title = "用户关注", businessType = BusinessType.DELETE, description = "取消关注用户：#{#request.followUserId}")
    public Result<Boolean> unfollowUser(@RequestBody FollowRequest request) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        // 调用服务层方法
        boolean success = userFollowService.unfollowUser(currentUserId, request.getFollowUserId());
        return Result.of(success, "取消关注成功", "取消关注失败");
    }

    /**
     * 检查关注状态
     */
    @GetMapping("/checkFollow")
    @Operation(summary = "检查关注状态", description = "检查当前用户是否关注了指定用户")
    public Result<FollowStatusVO> checkFollowStatus(@Parameter(description = "目标用户ID", required = true) @RequestParam Long targetUserId) {
        // 获取当前登录用户ID
        Long currentUserId = StpUtil.getLoginIdAsLong();
        // 调用服务层方法
        FollowStatusVO result = userFollowService.checkFollowStatus(currentUserId, targetUserId);
        return Result.success("查询成功", result);
    }

    /**
     * 获取用户关注数量
     */
    @GetMapping("/getFollowingCount")
    @Operation(summary = "获取用户关注数量", description = "获取指定用户的关注数量")
    public Result<Long> getFollowingCount(@Parameter(description = "用户ID", required = true) @RequestParam Long userId) {
        long count = userFollowService.getFollowingCount(userId);
        return Result.success("查询成功", count);
    }

    /**
     * 获取用户粉丝数量
     */
    @GetMapping("/getFollowersCount")
    @Operation(summary = "获取用户粉丝数量", description = "获取指定用户的粉丝数量")
    public Result<Long> getFollowersCount(@Parameter(description = "用户ID", required = true) @RequestParam Long userId) {
        long count = userFollowService.getFollowersCount(userId);
        return Result.success("查询成功", count);
    }

}
